﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApAPPPostProcessingCommand
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.AutomaticPathPlanner;
using DnProcessSimulateCommands.AutomaticPathPlanner.Planner;
using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;


namespace DnProcessSimulateCommands;

public class CApAPPPostProcessingCommand : CApAPPPlanCommandBase
{
  private List<CApAPPSegmentPostProcessingCommand> m_allThreadedCommand;
  private int m_currentTaskIndex;
  private long m_lastRefreshTime;
  private Stopwatch m_elapsedTimer;
  private List<List<CApAPPWaypointPlanSuccess>> m_allSuccessPlanCommand;
  private CApAPPWaypointPlanSuccess m_lastWapointSuccessSaved;

  public CApAPPPostProcessingCommand(
    List<CApAPPTask> i_tasks,
    KiAppPathPlanningParamsEx i_pathPlanningParams)
    : base(i_tasks, i_pathPlanningParams)
  {
    this.m_currentTaskIndex = -1;
    this.m_allThreadedCommand = new List<CApAPPSegmentPostProcessingCommand>();
    this.m_elapsedTimer = new Stopwatch();
    this.PlanningWasCancelled = false;
    this.m_allSuccessPlanCommand = this.GetAllPlanSuccessToPlan();
  }

  public List<CApAPPSegmentPostProcessingCommand> SegmentCommand() => this.m_allThreadedCommand;

  public override void Cancel() => this.PlanningWasCancelled = true;

  public override double GetProgress()
  {
    double num1 = 0.0;
    double num2 = (double) this.CountSubProblems();
    for (int index = 0; index < this.m_currentTaskIndex; ++index)
      num1 += 1.0 / num2;
    return num1 + this.GetProgress(this.m_currentTaskIndex) / num2;
  }

  public override double GetProgress(int i_subtaskRank)
  {
    double progress = 0.0;
    if (i_subtaskRank <= this.m_currentTaskIndex)
      progress = this.m_allThreadedCommand[i_subtaskRank].GetProgress();
    return progress;
  }

  protected override bool DoStart(
    ref CApAPPPlanCommandBase.PlanSuccessEventArgs errEvtArgs)
  {
    bool o_trackEndReached = false;
    bool flag = false;
    bool i_success = false;
    bool o_passTask = false;
    List<string> o_errorMessages = new List<string>();
    while (!flag && !this.PlanningWasCancelled)
    {
      i_success = this.StartNextOptimize(ref o_trackEndReached, ref o_passTask, ref o_errorMessages);
      if (i_success)
      {
        if (o_trackEndReached)
          flag = true;
        else if (!o_passTask)
        {
          while (!this.m_allThreadedCommand[this.m_currentTaskIndex].IsFinished && !this.PlanningWasCancelled)
          {
            this.m_allThreadedCommand[this.m_currentTaskIndex].onIdle();
            this.RefreshProgressUI();
          }
          if (this.PlanningWasCancelled && !this.m_allThreadedCommand[this.m_currentTaskIndex].IsFinished)
            this.m_allThreadedCommand[this.m_currentTaskIndex].Cancel();
        }
        else
          this.RefreshProgressUI();
      }
      else
        flag = true;
    }
    if (!i_success && !this.PlanningWasCancelled)
    {
      string i_details = this.ProcessErrorMessages(o_errorMessages);
      errEvtArgs = new CApAPPPlanCommandBase.PlanSuccessEventArgs(false, CApAPPMainWindowStringTable.PathPlanningErrorTitle, i_details);
    }
    else
      errEvtArgs = new CApAPPPlanCommandBase.PlanSuccessEventArgs(true);
    this.EndPlanning(i_success, errEvtArgs);
    return i_success;
  }

  private void RefreshProgressUI()
  {
    if (this.m_elapsedTimer.ElapsedMilliseconds - this.m_lastRefreshTime <= 500L)
      return;
    this.m_lastRefreshTime = this.m_elapsedTimer.ElapsedMilliseconds;
    this.UpdateProgress((object) this, new EventArgs());
    Application.DoEvents();
  }

  public bool StartNextOptimize(
    ref bool o_trackEndReached,
    ref bool o_passTask,
    ref List<string> o_errorMessages)
  {
    bool flag1 = true;
    o_trackEndReached = false;
    if (this.m_currentTaskIndex == this.TasksToPlan.Count - 1)
    {
      o_trackEndReached = true;
    }
    else
    {
      ++this.m_currentTaskIndex;
      CApAPPTask i_task = this.TasksToPlan[this.m_currentTaskIndex];
      if (this.m_currentTaskIndex >= 0 && this.TasksToPlan[this.m_currentTaskIndex].CountSubTasksToPlan() > 0)
      {
        int i_index = this.TasksToPlan[this.m_currentTaskIndex].RetrieveWaypointIndexFromSubTask(this.TasksToPlan[this.m_currentTaskIndex].SubTaskToPlan(this.TasksToPlan[this.m_currentTaskIndex].CountSubTasksToPlan() - 1));
        this.m_lastWapointSuccessSaved = i_task.Waypoint(i_index).WaypointPlanSuccess;
      }
      bool flag2 = false;
      if (i_task is CApAPPRoboticTask capAppRoboticTask)
      {
        if (this.PathPlanningParams.PostProcessOption == null)
        {
          if (CApAPPUtilities.IsRobotConnectedToRCS(capAppRoboticTask.Robot) && i_task.NeedsPostProcess(this.PathPlanningParams))
            flag2 = true;
        }
        else if (i_task.NeedsPostProcess(this.PathPlanningParams))
          flag2 = true;
      }
      if (flag2)
      {
        this.m_allThreadedCommand.Add(this.DoCreateThreadCommand(i_task, this.PathPlanningParams));
        this.m_elapsedTimer.Start();
        flag1 = this.m_allThreadedCommand[this.m_allThreadedCommand.Count - 1].StartPlanning(ref o_errorMessages);
        this.UpdatePlanSuccesses();
        if (!flag1)
          this.m_elapsedTimer.Reset();
        o_passTask = false;
      }
      else
      {
        flag1 = true;
        o_passTask = true;
      }
    }
    return flag1;
  }

  protected virtual CApAPPSegmentPostProcessingCommand DoCreateThreadCommand(
    CApAPPTask i_task,
    KiAppPathPlanningParamsEx i_pathPlanningParams)
  {
    return new CApAPPSegmentPostProcessingCommand(i_task, i_pathPlanningParams);
  }

  private void EndPlanning(
    bool i_success,
    CApAPPPlanCommandBase.PlanSuccessEventArgs planSuccessEventArgs)
  {
    foreach (CApAPPTask capAppTask in this.TasksToPlan)
      capAppTask.UpdateTxOperation();
    if (this.m_currentTaskIndex >= 0)
    {
      CApAPPTask capAppTask = this.TasksToPlan[this.m_currentTaskIndex];
      int i_index = this.TasksToPlan[this.m_currentTaskIndex].RetrieveWaypointIndexFromSubTask(this.TasksToPlan[this.m_currentTaskIndex].SubTaskToPlan(this.TasksToPlan[this.m_currentTaskIndex].CountSubTasksToPlan() - 1));
      if (capAppTask.Waypoint(i_index).WaypointPlanSuccess != CApAPPWaypointPlanSuccess.PostProcessingSuccess && capAppTask.Waypoint(i_index).WaypointPlanSuccess != CApAPPWaypointPlanSuccess.PostProcessingSimulationError)
        capAppTask.Waypoint(i_index).WaypointPlanSuccess = this.m_lastWapointSuccessSaved;
    }
    this.NotifyEndPlanning((object) this, planSuccessEventArgs);
    foreach (CApAPPTask capAppTask in this.TasksToPlan)
      capAppTask.RestoreInitialState();
  }

  public override int RetrieveIndexSubProblemFromWaypoint(CApAPPWaypoint i_wp) => 0;

  public override int CountSubProblems() => this.TasksToPlan.Count;

  public override long GetElapsedTime() => this.m_elapsedTimer.ElapsedMilliseconds;

  public override bool IsFinished(int i_subtaskRank)
  {
    bool flag = false;
    if (i_subtaskRank <= this.m_currentTaskIndex)
      flag = this.m_allThreadedCommand[i_subtaskRank].IsFinished;
    return flag;
  }

  private string ProcessErrorMessages(List<string> errorMessages)
  {
    StringBuilder stringBuilder = new StringBuilder();
    bool flag = false;
    foreach (string errorMessage in errorMessages)
    {
      if (!flag)
      {
        stringBuilder.AppendLine(CApAPPMainWindowStringTable.OptimizationSimulationError);
        flag = true;
      }
      stringBuilder.AppendLine();
      stringBuilder.AppendLine(errorMessage);
    }
    return stringBuilder.ToString();
  }

  private string ConvertFirstWayPointIndexToWayPointsString(int wayPointIndex)
  {
    string wayPointsString = "[Unknown waypoint]";
    if (wayPointIndex >= 0 && wayPointIndex < this.m_allThreadedCommand[this.m_allThreadedCommand.Count - 1].taskToPlan.CountWaypoints())
      wayPointsString = $"{this.m_allThreadedCommand[this.m_allThreadedCommand.Count - 1].taskToPlan.Waypoint(wayPointIndex).Name} - {this.m_allThreadedCommand[this.m_allThreadedCommand.Count - 1].taskToPlan.Waypoint(wayPointIndex + 1).Name}";
    return wayPointsString;
  }

  private string GetNewLineSeparator() => "________________________________________";

  public CApAPPTask CurrentTask
  {
    get
    {
      CApAPPTask currentTask = (CApAPPTask) null;
      if (this.m_currentTaskIndex >= 0 && this.m_currentTaskIndex < this.TasksToPlan.Count)
        currentTask = this.TasksToPlan[this.m_currentTaskIndex];
      return currentTask;
    }
  }

  protected List<List<CApAPPWaypointPlanSuccess>> GetAllPlanSuccessToPlan()
  {
    List<List<CApAPPWaypointPlanSuccess>> planSuccessToPlan = new List<List<CApAPPWaypointPlanSuccess>>();
    for (int index = 0; index < this.TasksToPlan.Count; ++index)
      planSuccessToPlan.Add(this.TasksToPlan[index].GetPlanSuccesses());
    return planSuccessToPlan;
  }

  public new virtual void UpdatePlanSuccesses()
  {
    if (this.m_currentTaskIndex < this.m_allSuccessPlanCommand.Count)
    {
      int i_index = this.TasksToPlan[this.m_currentTaskIndex].RetrieveWaypointIndexFromSubTask(this.TasksToPlan[this.m_currentTaskIndex].SubTaskToPlan(this.TasksToPlan[this.m_currentTaskIndex].CountSubTasksToPlan() - 1));
      this.m_lastWapointSuccessSaved = this.TasksToPlan[this.m_currentTaskIndex].Waypoint(i_index).WaypointPlanSuccess;
      this.TasksToPlan[this.m_currentTaskIndex].Waypoint(i_index).WaypointPlanSuccess = CApAPPWaypointPlanSuccess.WaitingBeforeCalc;
    }
    this.NotifyUpdateWaypointStatus();
  }

  internal bool GetCurrentSegmentIndex(ref int currentSegmentIndex)
  {
    bool currentSegmentIndex1 = true;
    if (this.m_allThreadedCommand.Count == 0)
      currentSegmentIndex1 = false;
    if (currentSegmentIndex1)
    {
      CApAPPSegmentPostProcessingCommand processingCommand = this.m_allThreadedCommand[this.m_allThreadedCommand.Count - 1];
      currentSegmentIndex1 = processingCommand != null && processingCommand.GetCurrentSegmentIndex(ref currentSegmentIndex);
    }
    return currentSegmentIndex1;
  }
}
